/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.cratos.xxgram.platf.friend;

import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import javax.annotation.Resource;

import org.redkale.boot.Application;
import org.redkale.net.http.RestMapping;
import org.redkale.net.http.RestService;
import org.redkale.net.http.WebSocketNode;
import org.redkale.service.RetResult;
import org.redkale.source.ColumnValue;
import org.redkale.source.FilterExpress;
import org.redkale.source.FilterFunc;
import org.redkale.source.FilterNode;
import org.redkale.source.Flipper;
import org.redkale.util.Comment;
import org.redkale.util.Sheet;
import org.redkale.util.Utility;

import com.cratos.xxgram.platf.base.BaseService;
import com.cratos.xxgram.platf.base.RetCodes;
import com.cratos.xxgram.platf.base.UserInfo;
import com.cratos.xxgram.platf.presetsecret.PresetsecretRecord;
import com.cratos.xxgram.platf.presetsecret.SecretRecord;
import com.cratos.xxgram.platf.rongcloud.BaseContent;
import com.cratos.xxgram.platf.rongcloud.BasicContent;
import com.cratos.xxgram.platf.rongcloud.RongCloudMessage;
import com.cratos.xxgram.platf.rongcloud.RongCloudService;
import com.cratos.xxgram.platf.user.UserDetail;

/**
 *
 * @author zhangjx
 */
@RestService(name = "friend", comment = "好友服务")
public class FriendService extends BaseService {

    private static FriendService friendService2;

	@Resource
    private RongCloudService rongCloudService;//融云服务类

    @Resource(name = "wsim")
    protected WebSocketNode webSocketNode;
      
    final Pattern isNum = Pattern.compile("^-?\\d+(\\.\\d+)?$");
            
    @RestMapping(name = "requestAddFriend", auth = true, comment = "申请添加好友")
    public RetResult<Integer> requestAddFriend(UserInfo userInfo, FriendAsk ask) {
        int userId = userInfo.getUserid();// 主动方ID
        int friend = ask.getFriendid();//非主动方ID
        String friendaskid = userId + "-" + friend + "-" + Utility.format36time(System.currentTimeMillis());
        ask.setUserid(userId);
        ask.setFriendaskid(friendaskid);
        ask.setCreatetime(System.currentTimeMillis());
        String messageConent = ask.getVerifymessage();
        BaseContent content = new BasicContent.TextMessage(userInfo.getUsername() + " 请求添加你为好友");
        Map<String, Object> attachMap = new HashMap<>();
        attachMap.put("invitetype", ask.getInvitetype());
        attachMap.put("userInfo", userInfo);
        attachMap.put("content", messageConent);
        content.attach(attachMap);// 添加附加邀请类型信息
        RongCloudMessage message = new RongCloudMessage(RongCloudService.SYSTEM_ID, friend, BasicContent.TextMessage.TYPE, content);
        message.setType(RongCloudMessage.PRIVATE);
        rongCloudService.pubMessage(message);// 发送请求消息
        source.insert(ask);// 保存入库
        return RetResult.success();
    }

    @Comment("申请添加好友")
    public RetResult<Integer> reqAddFriend(int userId, FriendAsk ask) {
        int friend = ask.getFriendid();//非主动方ID
        String friendaskid = userId + "-" + friend + "-" + Utility.format36time(System.currentTimeMillis());
        ask.setUserid(userId);
        ask.setFriendaskid(friendaskid);
        ask.setCreatetime(System.currentTimeMillis());
        source.insert(ask);// 保存入库
        return RetResult.success();
    }

    @RestMapping(name = "dealRequestMessage", auth = true, comment = "处理申请结果")
    public RetResult<Integer> dealRequestMessage(UserInfo userInfo, short invitetype, FriendAnswer answer) {
        int userId = answer.getUserid();// 申请方Id
        int friend = userInfo.getUserid();// 应答方ID
        answer.setFriendid(friend);
        long now = System.currentTimeMillis();
        String friendaskid = userId + "-" + friend + "-" + Utility.format36time(now);
        answer.setFriendaskid(friendaskid);
        answer.setCreatetime(now);
        int retCode = 0;
        if (FriendAnswer.ACCEPT == answer.getAnswer()) {
            logger.info("user : ===" + answer.getUserid() + "friendId ===" + answer.getFriendid());
            retCode = bindFrinedShip(invitetype, answer, now);
            // 同意添加好友处理
            if (retCode == 0) {
                BaseContent content = new BasicContent.TextMessage("add");
                content.attach(userInfo);
                RongCloudMessage message = new RongCloudMessage(RongCloudService.ACCPET_SYSTEM_ID, userId, BasicContent.TextMessage.TYPE, content);
                message.setType(RongCloudMessage.PRIVATE);// 系统消息
                rongCloudService.pubMessage(message);// 发送请求消息
            }
        }
        source.insert(answer);// 保存入库
        if (retCode > 0) {
            return RetCodes.retResult(retCode);
        }
        return RetResult.success();
    }

    @Comment("绑定好友关系")
    public int bindFrinedShip(short invitetype, FriendAnswer answer, long now) {
        int userId = answer.getUserid();
        int friendId = answer.getFriendid();
        UserDetail answerUser = source.find(UserDetail.class, userId);
        UserDetail askUser = source.find(UserDetail.class, friendId);
        if (answerUser == null || askUser == null) {
            return RetCodes.RET_FRIENDSHI_BINDFRIENDSHIP_FAILED;//绑定用户关系失败
        }
        FriendShip askFriendShip = new FriendShip();
        String askfriendshipid = userId + "-" + friendId;
        String answerfriendshipid = friendId + "-" + userId;

        askFriendShip.setCreatetime(now);
        askFriendShip.setUserid(userId);
        askFriendShip.setFriendid(friendId);
        askFriendShip.setFriendname(askUser.getUsername());
        askFriendShip.setInvitetype(invitetype);
        askFriendShip.setFriendshipid(askfriendshipid);

        FriendShip oldaskFriendShip = source.find(FriendShip.class, askfriendshipid);
        FriendShip oldanswerFriedShip = source.find(FriendShip.class, answerfriendshipid);
        if (oldaskFriendShip != null && oldanswerFriedShip != null) {
            return RetCodes.RET_FRIENDSHI_ALREADLY_IS_FIRIND;
        }
        FriendShip answerFriedShip = new FriendShip();
        answerFriedShip.setCreatetime(now);
        answerFriedShip.setUserid(friendId);
        answerFriedShip.setFriendid(userId);
        answerFriedShip.setFriendname(answerUser.getUsername());
        answerFriedShip.setInvitetype(invitetype);
        answerFriedShip.setFriendshipid(answerfriendshipid);

        if (oldaskFriendShip == null) {
            source.insert(askFriendShip);
        }
        if (oldanswerFriedShip == null) {
            source.insert(answerFriedShip);
        }
        return 0;
    }

    @RestMapping(name = "fetchFriendAskList", auth = true, comment = "查询好友申请记录")
    public RetResult fetchFriendAskList(UserInfo userInfo, Flipper flipper, FriendAskBean bean) {
        if (bean == null) {
            bean = new FriendAskBean();
        }
        if (flipper == null) {
            flipper = new Flipper(65535);
        }
        flipper.sort("createtime desc , answer,readstatus asc  ");
        bean.setFriendid(userInfo.getUserid());
        Sheet<FriendAsk> sheet = source.querySheet(FriendAsk.class, flipper, bean);
        source.updateColumn(FriendAsk.class, 
                    FilterNode.create("friendid", FilterExpress.EQUAL, userInfo.getUserid())
                    , ColumnValue.mov("readstatus", FriendAsk.READ_STATUS));
        return RetResult.success(sheet);
    }
    
    @RestMapping(name = "countFriendAskSize", auth = true, comment = "统计好友申请个数")
    public RetResult countFriendAsksize(UserInfo userInfo) {
    	int size = source
				.getNumberResult(FriendAsk.class, FilterFunc.COUNT, 0, "friendaskid", FilterNode
							.create("friendid", FilterExpress.EQUAL, userInfo.getUserid())
							.and("readstatus", FilterExpress.EQUAL, FriendAsk.UNREAD_STATUS))
				.intValue();
    	
        return RetResult.success(size);
    }
    
    
    @RestMapping(name = "clearFriendAskInfo", auth = true, comment = "根据条件清空申请记录")
    public RetResult clearFriendAskInfo(UserInfo userInfo, FriendAskBean bean) {
        FilterNode filterNode = FilterNode.create("friendid", FilterExpress.EQUAL, userInfo.getUserid());
        if (bean != null) {
            if (bean.getFriendaskid() != null) {
                filterNode.and("friendaskid", FilterExpress.EQUAL, bean.getFriendaskid());
            }
        }
        int rows  = source.delete(FriendAsk.class, filterNode);
        return RetResult.success(rows);
    }

    private Map<Integer, String> mapPresetsecretRecords(int userid) {
		FilterNode node = FilterNode.create("friendid", FilterExpress.EQUAL, userid);
		List<PresetsecretRecord> rows = source.queryList(PresetsecretRecord.class, node);
		if (rows != null) {
			rows.forEach(obj -> {
				SecretRecord secretRecord = source.find(SecretRecord.class, obj.getSecretrecordid());
				if (secretRecord != null) {
					obj.setSecret(secretRecord.getSecret());
				}
			});
			return rows.stream().collect(Collectors.toMap(PresetsecretRecord::getUserid,PresetsecretRecord::getSecret));
		}
		return new HashMap<Integer, String>();
    }
    
    @RestMapping(name = "fetchFriendShips", auth = true, comment = "查询好友列表")
    public RetResult fetchFriendShips(UserInfo userInfo, Flipper flipper, FriendShipBean bean) {
        if (bean == null) {
            bean = new FriendShipBean();
        }
        Map<Integer, String> presetsecretRecordMap = mapPresetsecretRecords(userInfo.getUserid());
        bean.setUserid(userInfo.getUserid());
        Sheet<FriendShip> sheet = source.querySheet(FriendShip.class, flipper, bean);
        Collection<FriendShip> rows = null;
        if ((rows = sheet.getRows()) != null && rows.size() > 0) {
            rows.forEach(obj -> {
            	int friendid = obj.getFriendid();
                obj.setFriend(source.find(UserInfo.class, friendid));
                if(presetsecretRecordMap.containsKey(friendid)) {
                	obj.setSecret(presetsecretRecordMap.get(friendid));
                	obj.setSecretstatus(FriendShip.HAVE_SECRET);
                }
            });
        }
        return RetResult.success(sheet);
    }

    @RestMapping(name = "fetchFriendShip", auth = true, comment = "qrcode 1 二维码扫描添加根据用户ID或者用户电话号码查询好友详情")
    public RetResult fetchFriendShip(UserInfo userInfo, String param, int qrcode) {
        FilterNode node = FilterNode.create("mobile", FilterExpress.EQUAL, param);
        Map<Integer, String> presetsecretRecordMap = mapPresetsecretRecords(userInfo.getUserid());
        // 非数字 参数无效处理
        if (!isNum.matcher(param).matches()) {
            return RetCodes.retResult(RetCodes.RET_FRIENDSHI_FRIENDINFO_NOTEXIT_FIRIND);
        }
        
        if (param.length() < 11 && Long.valueOf(param) < Integer.MAX_VALUE) {
            node.or("userid", FilterExpress.EQUAL, Integer.parseInt(param));
        }
        UserInfo friendUser = source.find(UserInfo.class, node);
        
        if (friendUser == null) {
            return RetCodes.retResult(RetCodes.RET_FRIENDSHI_FRIENDINFO_NOTEXIT_FIRIND);
        }
        int friendId = friendUser.getUserid();
        int userId = userInfo.getUserid();
        String friendshipId = userInfo.getUserid() + "-" + friendId;
        FriendShip friendShip = source.find(FriendShip.class, friendshipId);
        if (friendShip == null) {
            friendShip = new FriendShip();
            friendShip.setIsfriend(false);
            friendShip.setRelationship(FriendShip.RELATION_SHIP_STRANGER);
            friendShip.setFriendid(friendId);
            friendShip.setUserid(userId);
            friendShip.setFriendname(friendUser.getUsername());
            friendShip.setFriend(friendUser);
            // 添加好友过滤规则
            long syssetting = friendUser.getSyssetting();
            // 根据二维码查找 兼容群查询时返回结果
            if (qrcode != -1) {
                 if (qrcode == 1) {
            	  if ((syssetting & 32768) != 32768) {
                  	return RetCodes.retResult(RetCodes.RET_FRIENDSHI_FRIENDINFO_NOTEXIT_FIRIND);
                  }
                } else {
                    // 15位  ID
                    if ((syssetting & 16384) != 16384 
                                            && (Long.parseLong(param) <= Integer.MAX_VALUE)
                                            && friendUser.getUserid() == Integer.parseInt(param)) {
                             return RetCodes.retResult(RetCodes.RET_FRIENDSHI_FRIENDINFO_NOTEXIT_FIRIND);
                    }
                    // 14位 手机号
                    if ((syssetting & 8192) != 8192 
                                            && param.equals(friendUser.getMobile())) {
                             return RetCodes.retResult(RetCodes.RET_FRIENDSHI_FRIENDINFO_NOTEXIT_FIRIND);
                    }
                }
            }
        } else {
        	friendShip.setFriend(friendUser);
        }
        // 好友信息加密信息
        if(friendShip != null && presetsecretRecordMap.containsKey(friendShip.getFriendid())) {
        	friendShip.setSecret(presetsecretRecordMap.get(friendShip.getFriendid()));
        	friendShip.setSecretstatus(FriendShip.HAVE_SECRET);
        }
        return RetResult.success(friendShip);
    }
    
    @RestMapping(name = "delFriend", auth = true, comment = "根据好友ID删除好友")
    public RetResult delFriend(UserInfo userInfo, int friendId) {
    	// 校验参数有效性
		if (userInfo.getUserid() == 0 || friendId == 0) {
			return RetCodes.retResult(RetCodes.RET_PARAMS_ILLEGAL);
		}
        if (friendId == 0) return RetCodes.retResult(RetCodes.RET_PARAMS_ILLEGAL);// 校验参数必传问题
        int userid = userInfo.getUserid();
        String userFriendShipId = userid + "-" + friendId;
        String ffriendshipId = friendId + "-" + userid;
        FriendShip ffriendShip = source.find(FriendShip.class, ffriendshipId);
        FriendShip ufriendShip = source.find(FriendShip.class, userFriendShipId);
        if (ffriendShip != null) {
            source.insert(ffriendShip.createRandomHis());
        }
        if (ufriendShip != null) {
            source.insert(ufriendShip.createRandomHis());
        }
        source.delete(FriendShip.class, userFriendShipId);
        source.delete(FriendShip.class, ffriendshipId);
        source.delete(FriendAsk.class, FilterNode
        		.create("userid", FilterExpress.EQUAL, userInfo.getUserid()).and("friendid", FilterExpress.EQUAL, friendId)
        		.or(FilterNode.create("friendid", FilterExpress.EQUAL, userInfo.getUserid()).and("userid", FilterExpress.EQUAL, friendId)));
        BaseContent content = new BasicContent.TextMessage("del");
        content.attach(userInfo);
        RongCloudMessage message = new RongCloudMessage(RongCloudService.ACCPET_SYSTEM_ID, friendId, BasicContent.TextMessage.TYPE, content);
        message.setType(RongCloudMessage.PRIVATE);// 系统消息
//        rongCloudService.pubMessage(message);// 发送请求消息
        return RetResult.success();
    }

    @RestMapping(name = "updateFriendname", auth = true, comment = "更新好友备注")
    public RetResult updateFriendname(UserInfo userInfo, FriendShip bean) {
        String friendShipId = userInfo.getUserid() + "-" + bean.getFriendid();
        bean.setFriendshipid(friendShipId);
        String friendName = bean.getFriendname();
        // 校验好友备注是否合法
		if (/* friendName.isEmpty() || */friendName.length() > FriendShip.FRIENDNAME_MAXLEN) {
        	return RetCodes.retResult(RetCodes.RET_FRIENDSHIP_INVALID_FRIENDSHIPNAME);
        }
        return RetResult.success(source.updateColumn(bean, "friendname"));
    }

    @RestMapping(name = "updateBlackList", auth = true, comment = "更新好友关系黑名单")
    public RetResult updateBlackList(UserInfo userInfo, FriendShip bean) {
        String friendShipId = userInfo.getUserid() + "-" + bean.getFriendid();
        bean.setFriendshipid(friendShipId);
        source.updateColumn(bean, "relationship");// todo 添加异常处理
        //更新黑名单状态
        updateSystemSetting(userInfo, bean.getFriendid() + "", 3, bean.getRelationship() == FriendShip.RELATION_SHIP_BLACKLIST ? 1 : 0); 
        return RetResult.success(bean);
    }

    @RestMapping(name = "updateSystemSetting", auth = true, comment = "更新用户好友关系配置状态")
    public RetResult updateSystemSetting(UserInfo userInfo, String friendid, int index, int value) {
        String friendShipId = userInfo.getUserid() + "-" + friendid;
        FriendShip friendShip = source.find(FriendShip.class, friendShipId);
        if (friendShip == null) {
            return RetCodes.retResult(RetCodes.RET_FRIENDSHI_FRIENDINFO_NOTEXIT_FIRIND);
        }
        long oldVal = friendShip.getSyssetting();
        index = index - 1;
        long decVal = (long) Math.pow(2, index);
        long yuVal = 0xFFFFFFFF - decVal;
        long cValue = yuVal & oldVal;//减少  当前位的值  获得其他位数的值
        // 判断当前位数的值是否需要增加
        if (value == 1) {
            cValue = cValue + decVal;
        }
        source.updateColumn(FriendShip.class, friendShipId, ColumnValue.mov("syssetting", cValue));
        //更新字段值
        return RetResult.success(cValue);
    }

    @RestMapping(name = "updateChatbackground", auth = true, comment = "更新聊天背景")
    public RetResult updateChatbackground(UserInfo userInfo, FriendShip bean) {
        String friendShipId = userInfo.getUserid() + "-" + bean.getFriendid();
        FriendShip friendShip = source.find(FriendShip.class, friendShipId);
        if (friendShip == null) {
            return RetCodes.retResult(RetCodes.RET_FRIENDSHI_FRIENDINFO_NOTEXIT_FIRIND);
        }
        friendShip.setChatbackground(bean.getChatbackground());
        return RetResult.success(source.updateColumn(friendShip, "chatbackground"));
    }

    @Comment("更新用户好友头像")
    public RetResult updateAskFriendInfo(UserInfo user) {
    	return RetResult.success(source.updateColumn(FriendAsk.class, 
    				FilterNode.create("userid", user.getUserid()),
    				ColumnValue.mov("askusername", user.getUsername()), 
    				ColumnValue.mov("askuserface", user.getFace())));
    }
    @RestMapping(name = "updateRelstatus", auth = true, comment = "更新对好友的状态  20 隐身  10 正常显示")
    public RetResult updateRelstatus(UserInfo userInfo, int friendid, int relstatus) {
        if (!(friendid > 0) || !(relstatus > 0)) {
            return RetCodes.retResult(RetCodes.RET_PARAMS_ILLEGAL);
        }
        int rows = source.updateColumn(FriendShip.class, FilterNode
                .create("userid", FilterExpress.EQUAL, friendid)
                .and("friendid", FilterExpress.EQUAL, userInfo.getUserid()),
                ColumnValue.mov("relstatus", relstatus));
        if (rows > 0) {
            return RetResult.success(rows);
        }
        return RetCodes.retResult(RetCodes.RET_FRIENDSHI_FRIENDINFO_NOTEXIT_FIRIND);
    }

    @RestMapping(name = "fetchOnlineStatus", auth = true, comment = "查询好友在线状态")
    public RetResult fetchOnlineStatus(UserInfo userInfo, int userid) {
       return RetResult.success(webSocketNode.existsWebSocket(userid).join()) ;// 查询好友在线状态
    }
    
    @RestMapping(name = "fetchStealthFriends", auth = true, comment = "查询隐身状态好友 - 手机隐身添加需要调用")
    public RetResult fetchStealthFriends(UserInfo userInfo, Flipper flipper) {
        Sheet sheet = source.querySheet(FriendShip.class, flipper, FilterNode
                .create("friendid", FilterExpress.EQUAL, userInfo.getUserid())
                .and("relstatus", FilterExpress.EQUAL, FriendShip.REL_STATUS_STEALTH));
        return RetResult.success(sheet);
    }

    public void test() {
        Sheet<FriendShipHis> querySheet = source.querySheet(FriendShipHis.class, null, (FilterNode) null);
        System.out.println("querySheet===>>" + querySheet);
    }
 
    public static void main(String[] args) throws Exception {
        FriendService friendService = Application.singleton(FriendService.class);
        UserInfo userinfo = new UserInfo(300000001);
        RetResult rs =  friendService.fetchFriendAskList(userinfo, null, null);
        System.out.println(rs);
        
//        UserInfo userInfo = UserInfo.USER_SYSTEM;
//        userInfo.setUserid(300000004);
//        UserInfo find = friendService.source.find(UserInfo.class, 11);
//        friendService.fetchFriendShips(UserInfo.USER_SYSTEM, null, null);
//        friendService.test();
//        System.out.println("xxx");
//        System.out.println(find);
//        UserInfo userInfo = new UserInfo();
//        userInfo.setUserid(RongCloudService.SYSTEM_ID);//系统用户ID
//        System.out.println(Utility.uuid());
//        //        friendService.delFriend(userInfo, 300000005);
//        //        System.out.println("" + Long.MAX_VALUE);
//        //          System.out.println("" + Integer.MAX_VALUE);
//        FriendAsk ask = new FriendAsk();
//        ask.setVerifymessage("你好我是XXX请求添加你为好友!!!");
//        ask.setUserid(RongCloudService.SYSTEM_ID);
//        ask.setFriendid(300000004);
//        ask.setInvitetype((short) 10);
//        System.out.println("" + friendService.requestAddFriend(userInfo, ask));
//        FriendAnswer answer = new FriendAnswer();
//        answer.setAnswer((short)10);
//        answer.setFriendid(300000002);
//        answer.setUserid(300000001);
//        userInfo.setUserid(300000002);
//        Object obj = friendService.dealRequestMessage(userInfo,(short)1, answer);
//        System.out.println("obj===>>>" + obj);
//        FriendShipBean bean = new FriendShipBean();
//        System.out.println(friendService.fetchFriendShips(userInfo, null, bean));
//        Object o = friendService.fetchFriendShip(userInfo, "300000004");
//        System.out.println(friendService.fetchFriendShip(userInfo, "300000004"));
        Thread.sleep(1000 * 30);
    }
}
